跳到主要内容

Go 的 IO 工具包 ioutil

ioutil 库 就是一个工具包,里面主要是比较实用的函数,比如 ReadFile、WriteFile 等,唯一需要注意的是它们都是一次性读取和一次性写入,所以当读取的时候注意文件不能过大。

bufio VS ioutil 库:两者都提供了对文件的读写功能,唯一的不同就是 bufio 多了一层缓存的功能,这个优势主要体现读取大文件的时候,ioutil.ReadFile 是一次性将内容加载到内存,如果内容过大,很容易爆内存。所以它们一般结合使用

import (
"bufio"
"fmt"
"io/ioutil"
"os"
)

func main() {
fileObj, err := os.Open("config.yml")
if err != nil {
fmt.Println("文件打开失败:", err)
return
}

defer fileObj.Close()
reader := bufio.NewReader(fileObj)
buf, err := ioutil.ReadAll(reader)

if err != nil {
fmt.Println(err)
}

fmt.Printf("读取的文件内容: \n %s \n", string(buf))
}

快速使用

从文件读取数据:

func readByFile()  {
data, err := ioutil.ReadFile( "./lab8_io/file/test.txt")
if err != nil {
log.Fatal("err:", err)
return
}
fmt.Println("data", string(data)) // hello world!
}

把数据写入到文件:

// 后面这个 0644 是权限的意思
func writeFile() {
err := ioutil.WriteFile("./lab8_io/file/write_test.txt", []byte("hello world!"), 0644)
if err != nil {
panic(err)
return
}
}

这里的最后一个参数的用途在于授权系统的用户是否可以访问文件,其访问的权限又分三种

  • r 读的权限
  • w 写的权限
  • x 执行的权限

此参数在 Windows 操作系统上是没有作用的,该参数只会在 Unix-like, macOS 系统上起作用。

开头使用 0 的表示这是一个 8 进制的数字

这边先整理,0-7 每个数字权限的意义。

0   没有任何权限
1 可以执行
2 可以写
3 可以写、可以执行
4 可以读
5 可以读、可以执行
6 可以读、可以写
7 可以读、可以写、可以执行

所以

fmt.Println(os.FileMode(0660)) //-rw-rw----
  • 档案所有者可以有读写的权限
  • 群组用户可以有读写的权限
  • 其他用户没有任何权限

这个细节看 Linux 文件权限那篇笔记,这里只是为了快速回顾

丢弃输入

可以通过 ioutil.Discard 来丢弃打印结果

errorLog.SetOutput(ioutil.Discard)

包装 io.Reader 为 io.ReadCloser

有时候我们需要传递一个 io.ReadCloser 的实例,而我们现在有一个 io.Reader 的实例,比如:strings.Reader,这个时候 NopCloser 就派上用场了。

它包装一个 io.Reader,返回一个 io.ReadCloser,而相应的 Close 方法啥也不做,只是返回 nil

使用例:

body, _ := ioutil.ReadAll(resp.Body)
// body type is byte array.
resp.Body = ioutil.NopCloser(bytes.NewReader(body))